﻿
namespace KinonekoSoftware.Platform.Controls
{
    public class ContentHost : Control
    {
        static ContentHost()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ContentHost), 
                new FrameworkPropertyMetadata(typeof(ContentHost)));
            ViewModelProperty = DependencyProperty.Register(
                nameof(ViewModel),
                typeof(ManagedLifetimeObject),
                typeof(ContentHost),
                new PropertyMetadata(default(ManagedLifetimeObject), OnViewModelChanged));
            
            ContentPropertyKey = DependencyProperty.RegisterReadOnly(
                nameof(Content),
                typeof(object),
                typeof(ContentHost),
                new PropertyMetadata(default(object)));

            ContentProperty = ContentPropertyKey.DependencyProperty;
        }


        public static readonly DependencyProperty    ViewModelProperty;
        public static readonly DependencyProperty    ContentProperty;
        public static readonly DependencyPropertyKey ContentPropertyKey;
        
        private static void OnViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue is ManagedLifetimeObject vm)
            {
                try
                {
                    Control v;
                    
                    if (vm is ViewModelBase fs && fs.EnableViewCache)
                    {
                        if (fs.ViewCache is not null && fs.ViewCache
                                                          .TryGetTarget(out var cacheV))
                        {
                            v = (Control)cacheV;
                        }
                        else
                        {
                            v            = Xplat.Associate(vm);
                            fs.ViewCache = new WeakReference<object>(v);
                        }
                    }
                    else
                    {
                        v = Xplat.Associate(vm);
                    }
                    
                    d.SetValue(ContentPropertyKey, v);
                }
                catch(Exception ex)
                {
                    //
                    var temp = new InternalErrorPageVM(ex, vm.GetType());
                    var v    = Xplat.Associate(temp);

                    d.SetValue(ContentPropertyKey, v);
                }
            }
            else
            {
                d.ClearValue(ContentPropertyKey);
            }
        }



        public object Content
        {
            get => GetValue(ContentProperty);
            private set => SetValue(ContentPropertyKey.DependencyProperty, value);
        }

        public ManagedLifetimeObject ViewModel
        {
            get => (ManagedLifetimeObject)GetValue(ViewModelProperty);
            set => SetValue(ViewModelProperty, value);
        }
    }
}